<?php
/**
 * class App_Controller_User
 *
 * @author kim, andrew, leo
 */
class App_Controller_User extends App_Controller_Abstract
{
    /**
     * default action
     */
    public function indexAction()
    {
        $this->_redirectIfNotLoggedIn();
        $form = new App_Form_User_SimpleSearch();
        $this->view->formSearch=$form;
        $geoModel = new App_Model_Geo();
        $this->view->states = $geoModel->listStatesInCountry('United States');
    }

    /**
     * user login action
     *
     * @return null
     */
    /*
    public function oldLoginAction()
    {
        if (App_Model_User::isLoggedIn()) {
            $this->_helper->redirector('index', 'index');
        }

        // login form object
        $form = new App_Form_User_Login();

        if ($this->getRequest()->isPost()) {
            $data = $this->getRequest()->getPost();

            // validate post data
            if ($form->isValid($data)) {
                // process user login
                $userModel = new App_Model_User();
                $result = $userModel->getLoginResult($form->getValues());

                if (true === $result) {
                    if (isset($data['referer'])) {
                        $this->_redirect($data['referer']);
                    } else {
                        $this->_helper->redirector('index', 'index');
                    }
                } else {
                    $this->view->errorMsg = $result;
                }
            } else {
                $form->populate($data);
            }
        }

        // set default email if passed
        $email = $this->_getParam('email');
        if (App_Model_Mail::isEmail($email)) {
            $form->email_username->setValue($email);
        }

        $this->view->referer = $this->_getParam('referer');
        $this->view->formLogin = $form;
    }
	*/

    /**
     * user login action
     *
     * @return json type error message if fail to login, redirect to index page if success
     */
    public function loginAction()
    {
        if (App_Model_User::isLoggedIn()) {
            $this->_helper->redirector('index', 'index');
        }

        $msg = $this->_helper->FlashMessenger->getMessages();
        if(is_array($msg) && !empty($msg[0]))
        {
            $this->view->tipMsg = $msg[0];
        }

        $form = new App_Form_User_Login();
        $this->view->formLogin = $form;

        if ($this->getRequest()->isPost())
        {
            $data = $this->getRequest()->getPost();
            $userModel = new App_Model_User();

            $result = $userModel->getLoginResult($data);

            if (true === $result)
            {
                $returnData['error'] = false;
                if (isset($data['referer']) && $data['referer'] != null)
                {
                    $returnData['html'] = $data['referer'];
                }
            }
            else
            {
                $returnData['error'] = true;
                $returnData['msg'] = $result;
            }

            return $this->_helper->json($returnData);
        }
    }

    /**
     * user logout action
     * redirect to login when user logout
     *
     * @return null
     */
    public function logoutAction()
    {
        App_Model_User::logout();
        $this->_redirectIfNotLoggedIn();
    }

    /**
     * user register action
     *
     * @todo - test carefully
     * @author kim
     *
     * @return null|json
     */
    public function registerAction()
    {
        $isTesting = $this->_getParam('is_testing', false);

        // for QA testing
        if (APPLICATION_ENV == 'development' and $isTesting) {
            $this->view->isTesting = $isTesting;
            $testUserModel = new App_Model_User();
            $this->view->testUserId = $testUserModel->getUserIdByLoginEmail($isTesting);
        }

        // login form object
        $form = new App_Form_User_Register();

        $geoModel = new App_Model_Geo();
        $this->view->states = $geoModel->listStatesInCountry('United States');

        if ($this->getRequest()->isPost()) {
            $data = $this->getRequest()->getPost();
            //var_dump($data);die; // for testing

            // validate post data and process user register
            if ($form->isValid($data)) {
                $loginData = $form->getValues();
                $userModel = new App_Model_User();

                // for QA testing
                if ($isTesting) {
                    /**
                     * is testing try to send register email and return to testing
                     */
                    if ($userId = $userModel->getUserIdByLoginEmail($loginData['email'])) {
                        if ($userModel->sendRegisterEmail($userId)) {
                            $this->_helper->json->sendJson(array(
                                'result' => $userId,
                                'success' => true,
                            ));
                        }
                    }
                } else {
                    /**
                     * not testing, do the register, then return json
                     */
                    if ($userId = $userModel->getRegisterResult($loginData)) {
                        $userModel->sendRegisterEmail($userId);

                        // relogin current user
                        App_Model_User::logout();
                        $login = array('email_username' => $loginData['email'], 'password' => $loginData['password_new']);
                        $userModel->getLoginResult($login);

                        $this->_helper->json->sendJson(array(
                            'result' => $userId,
                            'success' => true,
                        ));
                    } else {
                        $this->_helper->json->sendJson(array(
                            'result' => array('errorMsg' => 'Register fails, please check inputs again'),
                            'success' => false,
                        ));
                    }
                }
            } else {
                foreach ($form->getErrors() as $element => $errors) {
                    if (!empty($errors)) {
                        $message .= $element . ' : ' . implode(', ', $errors) . "\n";
                    }
                }
                App_Model_Log::write(new exception($message));
                //$form->populate($data);
                $this->_helper->json->sendJson(array('result' => array('errorMsg' => 'Register fails, please try again later', 'elements' => $form->getErrors()), 'success' => false));
            }
        }

        $captcha = $form->getElement('captcha')->getCaptcha();
        $captchaId = $captcha->generate();
        $captchaImgSrc = $captcha->getImgUrl().$captcha->getId().$captcha->getSuffix();

        $this->view->formRegister = $form;
        $this->view->captchaImgSrc = $captchaImgSrc;
        $this->view->captchaId = $captchaId;
    }

    /**
     * upload the avatar
     *
     * @return null
     */
    public function uploadAvatarAction()
    {
        $userId = $this->_getParam('upload_photo_user_id');

        /*if (!$userId) {
            throw new exception('App must provide user id!');
        }*/

        $form = new App_Form_Photo_Upload();

        if (!empty($userId)) {
            $data = $this->getRequest()->getParams();
            if ($form->isValid($data)) {

                // do uploading/resizing if photos received
                if ($form->upload->receive()) {

                    $type = 'user';
                    $albumId = App_Model_AlbumAbstract::getDefaultAlbumId($type, $userId);
                    if ($albumId) {
                        $photos = (array)$form->upload->getFileName('upload');

                        $photosUploaded = App_Model_PhotoAbstract::doUpload($type, $userId, $albumId, $photos);
                        App_Model_PhotoAbstract::doDefaultCrop($type, $photosUploaded[0]['id']);

                        if (!empty($photosUploaded)) {
                            //$userAvatar = App_Model_PhotoAbstract::getAvatar($photosUploaded[0], 'user', 'thumb_big', array('alt' => 'thumb big'));
                            $userAvatar = App_Model_PhotoAbstract::getSrc($photosUploaded[0], 'user', 'thumb_big');
                            $userAvatarFull = App_Model_PhotoAbstract::getSrc($photosUploaded[0], 'user', 'full');
                            $response['avatar'] = $userAvatar . ':' . $userAvatarFull . ':' . $photosUploaded[0]['id'];
                            $response['errors'] = false;
                        }
                    } else {
                        $response['errors'] = 'Unable to create album!';
                    }
                } else {
                    $messages = $form->upload->getMessages();
                    //throw new Exception(implode(', ', $messages));
                    $response['errors'] = implode(', ', $messages);
                }
            } else {
                $response['errors'] = 'Invalid data provided.';
            }

            if (empty($response['errors'])) echo 'success:' . $response['avatar'];
            else echo 'fail:' . $response['errors'];

        } else {
        	$response['errors'] = 'Invalid user.';
        	echo 'fail:' . $response['errors'];
        }
        exit;
    }

    /**
     * do cropping of user's avatar
     */
    public function cropAvatarAction()
    {
        $type = $this->_getParam('type');
        $photoId = $this->_getParam('photo_id');
        if ($type and $photoId) {
            $photoModel = App_Model_PhotoAbstract::createInstance($type);
            $photo = $photoModel->getById($type, $photoId);
            if ($photo) {
                $params = $this->getRequest()->getParams();
                $result = App_Model_PhotoAbstract::doCrop($type, $photo, $params);
                $response = array('errors'=>false, 'message'=>'ok');
            }
        }
        $this->_helper->json->sendJson($response);
    }

    /**
     * account activating
     */
    public function activateAction()
    {
        $code = $this->_getParam('code');

        if(!empty($code))
        {
            list($email, $activationCode) = explode("|", base64_decode($code));
            $userModel = new App_Model_User();

            // if the user does NOT need to activate, redirect to home page
            if($userModel->needActivate($email))
            {
                $result = $userModel->activateUser($email, $activationCode);

                if($result)
                {
                    $msg = "congratulations, your account has been activated successfully";
                    $this->_helper->FlashMessenger("$msg");
                    if(App_Model_User::isLoggedIn()) { $this->_helper->redirector('index', 'index'); }
                    else { $this->_helper->redirector('login', 'user'); }
                }
                else
                {
                    $msg = "Invalid activation code, please click the link on the email sent to you.";
                }
                $this->view->activate = true;
                $this->view->message = $msg;
            }
            else
            {
                $this->_helper->redirector('index', 'index');
            }
        }
        else // show send activation code page
        {
            $this->view->activate = false;
            $formModel = new App_Form_User_SendActivation();
            $captcha = $formModel->getElement('captcha')->getCaptcha();
            $captchaId = $captcha->generate();
            $captchaImgSrc = $captcha->getImgUrl().$captcha->getId().$captcha->getSuffix();

            $this->view->form = $formModel;
            $this->view->captchaImgSrc = $captchaImgSrc;
            $this->view->captchaId = $captchaId;

        }
    }

    /**
     * Sends an activation email to user
     */
    public function sendActivationAction()
    {
        $data = $this->getRequest()->getPost();
        $formModel = new App_Form_User_SendActivation();
        $response['error'] = true;

        if($formModel->isValid($data))
        {
            $values = $formModel->getValues();
            $email = $values['email'];
            $userModel = new App_Model_User();

            if($userModel->needActivate($email))
            {
                $result = $userModel->sendActivationEmail($email);

                if($result === true)
                {
                    $response['error'] = false;
                    $this->_helper->FlashMessenger("Activation mail has been sent to you email address successfully");
                    if(App_Model_User::isLoggedIn()) { $response['html'] = $this->view->L('index', 'index'); }
                    else { $response['html'] = $this->view->L('user', 'login'); }

                }
                else
                {
                    $response['msg'] = "failed to send activation mail, please try again later";
                }
            }
            else
            {
                $response['msg'] = "incorrect email address, pleace check it again";
            }
        }
        else
        {
            $response['msg'] = "please check your email and verification word";
        }
        return $this->_helper->json($response);
    }

    /**
     * refresh captcha/verification code
     */
    public function refreshCaptchaAction()
    {
        $form = new App_Form_User_SendActivation();
        $captcha = $form->getElement('captcha')->getCaptcha();

        $data = array();

        $data['id']  = $captcha->generate();
        $data['src'] = $captcha->getImgUrl() .
                       $captcha->getId() .
                       $captcha->getSuffix();

       return $this->_helper->json($data);
    }

    /**
     * reset password if user forgot the password
     * keep in mind that this function update "logins" but not "users"
     *
     * @todo - should throw exception or not?
     *
     * @return null
     */
    public function resetPwdAction()
    {
        $userId = App_Model_User::getStoredMyUserId();
        $userModel = new App_Model_User();
        if ($userModel->needActivate($userId)) {
            $this->_helper->FlashMessenger("You need to activate your account before changing your password. <a href=\"".$this->view->L('user', 'activate')."\">Activate now</a>");
            $this->_helper->redirector('index', 'index');
        }

        // reset password form object
        $form = new App_Form_User_ResetPwd();
        if ($this->getRequest()->isPost() || $this->getRequest()->isXmlHttpRequest()) {
            $data = $this->getRequest()->getPost();
            $response['error'] = true;
            // validate post data
            if ($form->isValid($data)) {

                // try to set the key for password reset
                $email = $form->getValue('email');
                // try to set the new confirm hash, and return the login id
                if ($loginId = $userModel->setPasswordKey($email)) {

                    // try to send the reset password email by account's email
                    if ($userModel->sendResetPwdEmail($loginId)) {
                        $response['error'] = false;
                        $response['html'] = $this->view->L('user', 'reset-pwd', array('is_email_sent' => true));
                    } else {
                        $response['msg'] = 'Unable to send email, please try again later';
                    }
                } else {
                    $response['msg'] = 'Sorry, email address can not be found';
                }
            } else {
                $response['msg'] = 'Please check your email address and verify code';
                $form->populate($data);
            }

            if($this->getRequest()->isXmlHttpRequest()) { return $this->_helper->json($response); }
        }

        $this->view->isEmailSent = $this->_getParam('is_email_sent');
        $captcha = $form->getElement('captcha')->getCaptcha();
        $captchaId = $captcha->generate();
        $captchaImgSrc = $captcha->getImgUrl().$captcha->getId().$captcha->getSuffix();

        $this->view->formResetPwd = $form;
        $this->view->captchaImgSrc = $captchaImgSrc;
        $this->view->captchaId = $captchaId;
    }

    /**
     * reset password confirm
     *
     * @return null
     */
    public function resetPwdConfirmAction()
    {
        $userModel = new App_Model_User();
        $userId = App_Model_User::getStoredMyUserId();
        if ($userModel->needActivate($userId)) {
            $this->_helper->FlashMessenger("You need to activate your account before changing your password. <a href=\"".$this->view->L('user', 'activate')."\">Activate now</a>");
            $this->_helper->redirector('index', 'index');
        }

        // user email and the hash
        $code = $this->_getParam('code');
        $form = new App_Form_User_ResetPwdConfirm();

        if ($this->getRequest()->isPost()) {
            $data = $this->getRequest()->getPost();
            $response['error'] = true;
            // validate post data
            if ($form->isValid($data)) {
                // try to reset password and get the feedback message
                if ($result = $userModel->getResetPasswordResult($form->getValues())) {
                    // $this->view->message = 'Password reseted.';
                    $response['error'] = false;
                    $this->_helper->FlashMessenger("Password has been reset successfully");
                    if(App_Model_User::isLoggedIn()) { $response['html'] = $this->view->L('index', 'index'); }
                    else { $response['html'] = $this->view->L('user', 'login'); }
                } else {
                    $response['msg'] = 'Unable to reset the password of ' . $data['email'];
                }
            } else {
                $form->populate($data);
                $response['msg'] = "Please check your new password";
            }
            return $this->_helper->json($response);
        } else {
            $this->view->resetPwd = false;
            if(!empty($code)) {
                $code = base64_decode($this->_getParam('code'));
                $emailAndKey = explode("|", $code);
                if (isset($emailAndKey[0]) and isset($emailAndKey[1])) {
                    $email = $emailAndKey[0];
                    $key = $emailAndKey[1];
                    // hidden fields that keep the email and hash
                    $form->setDefaults(array('email' => $email, 'key' => $key));
                    $this->view->email = $email;
                    $this->view->formResetPwdConfirm = $form;
                    $this->view->resetPwd = true;
                }
            }
            if (!$this->view->resetPwd) {
                $this->view->message = "invalid code, please click the link in the email we sent to you.";
            }
        }
    }

    /**
     * forget username
     */
    public function findUsernameAction()
    {
        $form = new App_Form_User_FindUsername();

        if ($this->getRequest()->isPost()) {
            $data = $this->getRequest()->getPost();
            $response['error'] = true;
            // validate post data
            if ($form->isValid($data)) {

                // try to set the key for password reset
                $email = $form->getValue('email');
                $userModel = new App_Model_User();

                // try to set the new confirm hash, and return the login id
                if ($userModel->checkEmailExists($email)) {

                    // try to send the reset password email by account's email
                    if ($userModel->sendFindUsernameEmail($email))
                    {
                        $this->_helper->FlashMessenger("Username has been sent to your mailbox successfully");
                        $response['error'] = false;
                        if(App_Model_User::isLoggedIn()) { $response['html'] = $this->view->L('index', 'index'); }
                        else { $response['html'] = $this->view->L('user', 'login'); }
                    }
                    else {
                        $response['msg'] = 'Unable to send email, please try again later';
                    }
                }
                else {
                    $response['msg'] = 'Sorry, email address can not be found';
                }
            }
            else {
                $response['msg'] = 'Invalid email address or verify code!';
                $form->populate($data);
            }
            return $this->_helper->json($response);
        }

        $this->view->isEmailSent = $this->_getParam('is_email_sent');

        $captcha = $form->getElement('captcha')->getCaptcha();
        $captchaId = $captcha->generate();
        $captchaImgSrc = $captcha->getImgUrl().$captcha->getId().$captcha->getSuffix();

        $this->view->form = $form;
        $this->view->captchaImgSrc = $captchaImgSrc;
        $this->view->captchaId = $captchaId;
    }

    /**
     * Search member
     *
     * @return null
     */
    public function searchAction()
    {
        $this->_redirectIfNotLoggedIn();
        // search form object
        $form = new App_Form_User_SimpleSearch();

        if ($this->getRequest()->isGet()) {
            $params = $this->getRequest()->getParams();
            if ($form->isValid($params)) {
                $data = $form->getValues();
                if(isset($params['sort_by']) && !empty($params['sort_by'])) { $data['sort_by'] = $params['sort_by']; }

                $page = $this->_getParam('page', 1);
                $count = $this->_getParam('count', 10);
                if ($count > 100) { $count = 100; }

                $userModel = new App_Model_User();
                $result = $userModel->searchUsers($data, $page, $count);

                if ($result['total_count']) {
                    $paginator = App_Model_Pagination::factory($result['results'], $result['total_count'], $page, $count);
                    $this->view->paginator = $paginator;
                    $this->view->sortBy = isset($data['sort_by']) ? $data['sort_by'] : '';
                }
            } else {
                $data = $form->getValues();
                $form->populate($data);
            }
        }

        $this->view->formSearch = $form;
        $geoModel = new App_Model_Geo();
        $this->view->states = $geoModel->listStatesInCountry('United States');
    }

    /**
     * see similar users
     */
    public function similarAction()
    {
    }

    /**
     * user account management
     *
     * @todo
     * 1. user account management
     * 2. pass the return url then the action can return to account after user login
     */
    public function accountAction()
    {
        $this->_redirectIfNotLoggedIn();
    }

    /**
     * list recent visitors
     */
    public function visitorsAction()
    {
        $this->_redirectIfNotLoggedIn();
        $page = $this->_getParam('page', 1);
        $count = $this->_getParam('count', 10);
        if ($count > 100) { $count = 100; }

        $userModel = new App_Model_User();
        $result = $userModel->getVisitors(App_Model_User::getStoredMyUserId(), $page, $count);

        if ($result['total_count']) {
            $paginator = App_Model_Pagination::factory($result['results'], $result['total_count'], $page, $count);
            $this->view->paginator = $paginator;
        }
    }

    /**
     * ajax post save area
     *
     * @return json
     */
    public function ajaxSaveAreaAction()
    {
        $errors = 'updated fail';
        if (App_Model_User::isLoggedIn() && $this->getRequest()->isPost()){
            $userModel = new App_Model_User();
            list($city, $state) = explode(',', $this->getRequest()->getParam('city_state'));
            $city = trim($city);
            $state = trim($state);
            $geo = new App_Model_Geo();
            $local = $geo->getLocalInfoFromCSC('United States', $state, $city);
            $user = array('id' => App_Model_User::getStoredMyUserId(),
                          'city' => $city,
                          'state' => $state,
                          'local_id' => $local['id']);
            $result = $userModel->update($user);
            if ($result >= 0) {
                $errors = false;
                $response['html'] = 'updated success';
            }
        }
        $response['errors'] = $errors;
        $this->_helper->json->sendJson($response);
    }

    /**
     *  Ajax get cities by state
     *
     *  @return json
     */
    public function ajaxCityStateAutocompleteAction()
    {
        $word = $this->getRequest()->getParam('word');
        $country =  $this->getRequest()->getParam('country');

        $geo = new App_Model_Geo();
        if ($country) {
            $cities = $geo->getCityStateAutocomplete($word, $country);
        } else {
            $cities = $geo->getCityStateAutocomplete($word);
        }

        $data = array();
        foreach($cities as $city) {
            $data[] = $city['city'].', '.$city['state'];
        }
        $this->_helper->json->sendJson($data);
    }

    /**
     *  Ajax check city and state
     *
     *  @return json
     */
    public function ajaxCheckCityStateAction()
    {
        $result = false;
        list($city, $state) = explode(',', $this->_getParam('city_state', ''));
        $city = trim($city);
        $state = trim($state);
        if ($city and $state) {
            $geo = new App_Model_Geo();
            $result = $geo->checkCityStateExists($city, $state);
        }
        $this->_helper->json->sendJson($result);
    }

    /**
     * Ajax check email if exist
     *
     * @return boolean - if email already exists, return false, otherwise return true
     */
    public function ajaxCheckEmailAction()
    {
        // for QA testing
        if (APPLICATION_ENV == 'development') {
            if ($this->_getParam('is_testing', false)) {
                $this->_helper->json->sendJson(true);
            }
        }

        // else we check if email really exists
        $email = $this->getRequest()->getParam('email');
        $userModel = new App_Model_User();
        $result = $userModel->checkEmailExists($email) ? false : true;
        $this->_helper->json->sendJson($result);
    }

    /**
     * ajax add user's bio
     *
     * @return null
     */
    public function ajaxAddBioAction()
    {
        $form = new App_Form_User_AddBio();

        if ($this->getRequest()->isPost()) {
            $response['errors'] = true;
            $data = $this->getRequest()->getParams();

            if ($form->isValid($data)) {
                $userModel = new App_Model_User();
                if ($userModel->updateUserText($data['bio_user_id'], 'bio', $data['bio'])) {
                    $response['errors'] = false;
                }
            }
        }
        return $this->_helper->json($response);
    }

    /**
     * ajax add user's bio
     *
     * @return null
     */
    public function ajaxAddBioAndFoodTypesAction()
    {
        $form = new App_Form_User_AddBio();

        if ($this->getRequest()->isPost()) {
            $response['errors'] = true;
            $data = $this->getRequest()->getParams();
            $bio = array('bio'=>$data['bio']);

            if ($form->isValid($bio)) {
                $userModel = new App_Model_User();
                if ($userModel->updateUserText($data['bio_user_id'], 'bio', $data['bio'])) {
                    $response['errors'] = false;
                }

                if (!empty($data['type_favorites']))
                    $userModel->updateUserFavoriteTypes($data['bio_user_id'], $data['type_favorites']);

                $userModel->updateMailingList($data['bio_user_id'], $data['mailing_list']);
            }
        }
        return $this->_helper->json($response);
    }

    /**
     * test register email
     *
     * @return null
     */
    public function testRegisterEmailAction()
    {
        if (APPLICATION_ENV == 'development') {
            $userId = $this->getRequest()->getParam('user_id');
            if ($userId) {
                if (mail('xqpmjh@gmail.com', 'My Subject', 'mail() works')) {
                    echo 'Mail() works';
                } else {
                    echo 'Mail() fails';
                }
                $userModel->sendRegisterEmail($userId);
            } else {
                die('need user id');
            }
        }
        //die;
    }


}
